#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "nvs_flash.h"
#include "esp_sntp.h"

#include "wifi_app_task.h"
#include "nvs_manager.h"
#include "aliot_mqtt.h"

static const char *TAG = "wifi";

static wifi_manager_callback  s_wifi_cb = NULL;

/**
 * @brief WiFi 事件处理
 * @param ev WiFi 事件类型
 */
void wifi_event_handler(wifi_ev_t ev, void *data)
{
    if (ev == WIFI_EV_SNTP) {
       
    }
    else if (ev == WIFI_EV_DISCONNECTED) {
        
    }
    else if (ev == WIFI_EV_READY) {
        
    }
}

/**
 * @brief WiFi 事件处理函数
 * @param arg 用户参数
 * @param event_base 事件基类型
 * @param event_id 事件ID
 * @param event_data 事件数据
 */
static void wifi_app_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT) {
        switch (event_id) {
        case WIFI_EVENT_STA_START:          // WIFI 就绪
            esp_wifi_connect();
            if (s_wifi_cb)
                s_wifi_cb(WIFI_EV_READY, 0);
            break;
            
        case WIFI_EVENT_STA_CONNECTED:      // 连接 AP 成功
            ESP_LOGI(TAG, "Connected to AP");
           
            break;
            
        case WIFI_EVENT_STA_DISCONNECTED:   // 连接 AP 失败
            if (s_wifi_cb)
                s_wifi_cb(WIFI_EV_DISCONNECTED, 0);
            break;
        
        case WIFI_EVENT_SCAN_DONE:          // 扫描结束
            ESP_LOGI(TAG, "scan to AP");
            break;
        default:
            break;
        }
    }
    else if (event_base == IP_EVENT) {
        switch(event_id) {
        case IP_EVENT_STA_GOT_IP:
            ESP_LOGI(TAG, "Got IP address");
            aliot_mqtt_start();
            break;
        case IP_EVENT_STA_LOST_IP:       //失联
            if(s_wifi_cb)
                s_wifi_cb(WIFI_EV_DISCONNECTED, 0);
            break;
        default:
            break;
        }
    }
}

// 处理WIFI任务
static void wifi_manager_task(void* param)
{
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    if (!sta_netif) {
        ESP_LOGE(TAG, "Failed to create default WiFi STA");
        return;
    }

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    // 注册事件处理器
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_app_event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_app_event_handler, NULL));

    // 读取 nvs 中 wifi 名称和密码
    nv_device_info_t *device_info_cache = get_device_info_cache();

    // 配置 WiFi
    wifi_config_t wifi_config = {
        .sta = {
            // .ssid = NVS_WIFI_SSID,
            // .password = NVS_WIFI_PASSWORD,
            .threshold.authmode = WIFI_AUTH_WPA2_PSK,
            .pmf_cfg = {
                .capable = true,
                .required = false,
            },
        },
    };
    strncpy((char *)wifi_config.sta.ssid, device_info_cache->wifi_info.ssid, strlen(device_info_cache->wifi_info.ssid) - 1);
    wifi_config.sta.ssid[strlen(device_info_cache->wifi_info.ssid) - 1] = '\0';
    strncpy((char *)wifi_config.sta.password, device_info_cache->wifi_info.password, strlen(device_info_cache->wifi_info.password) - 1);
    wifi_config.sta.password[strlen(device_info_cache->wifi_info.password) - 1] = '\0';

    // 设置并启动 WiFi
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());

    while (1) {
        vTaskDelay(pdMS_TO_TICKS(1000)); // 1秒延迟（避免空转消耗CPU）
    }
}

/**
 * @brief 初始化 WiFi STA 模式
 * @param f WiFi 事件回调函数
 * @return esp_err_t 错误码
 */
esp_err_t wifi_manager_init(wifi_manager_callback f)
{
    xTaskCreatePinnedToCore(wifi_manager_task, "wifi_manager", 4096, NULL, 1, NULL, tskNO_AFFINITY);
    s_wifi_cb = f;

    return ESP_OK;
}

/**
 * @brief wifi 应用程序初始化
 * @return esp_err_t 错误码
 */
esp_err_t wifi_app_task_init(void)
{
    esp_err_t err = ESP_FAIL;

    // 初始化 WiFi STA 模式
    err = wifi_manager_init(wifi_event_handler);

    return err;
}

/**
 * @brief WiFi 设置ssid和密码
 * @param ssid 用户名称
 * @param password 用户密码
 */
void wifi_manager_set_ssid(char *ssid, char *password)
{
    wifi_config_t wifi_config = {
        .sta = {
            .threshold.authmode = WIFI_AUTH_WPA2_PSK,
            .pmf_cfg = {
                .capable = true,
                .required = false,
            },
        },
    };

    // 重新配置WIFI的ssid和password
    memcpy(wifi_config.sta.ssid, ssid, strlen(ssid));
    wifi_config.sta.ssid[strlen(ssid)] = 0;
    memcpy(wifi_config.sta.password, password, strlen(password));
    wifi_config.sta.password[strlen(password)] = 0;

    ESP_ERROR_CHECK(esp_wifi_disconnect());
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
}
